// Package jwt
// Created by GoLand
// @User: lenora
// @Date: 2024/1/11
// @Time: 13:35

package jwt

import (
	"errors"
	"github.com/gin-gonic/gin"
	"github.com/golang-jwt/jwt/v5"
	"github.com/redis/go-redis/v9"
	"time"
)

var JWTKey = []byte("fnkjnRjpgMZFpynsrSedsOQmtywHtidH")

type RedisJWTHandler struct {
	client       redis.Cmdable
	rtExpiration time.Duration
}

func NewRedisJWTHandler(cmdable redis.Cmdable) Handler {
	return &RedisJWTHandler{
		client:       cmdable,
		rtExpiration: time.Hour * 24 * 7,
	}
}

func (h *RedisJWTHandler) SetJWTToken(ctx *gin.Context, uid uint64, uuid string) error {
	uc := UserClaims{
		Id:        uid,
		Ssid:      uuid,
		UserAgent: ctx.GetHeader("User-Agent"),
		RegisteredClaims: jwt.RegisteredClaims{
			ExpiresAt: &jwt.NumericDate{time.Now().Add(time.Minute * 10)},
		},
	}
	token := jwt.NewWithClaims(jwt.SigningMethodHS256, uc)

	tokenStr, err := token.SignedString(JWTKey)
	if err != nil {
		return err
	}
	ctx.Header("x-jwt-token", tokenStr)
	return nil
}

func (h *RedisJWTHandler) ClearJWTToken(ctx *gin.Context) error {
	ctx.Header("x-jwt-token", "")

	uc := ctx.MustGet("web").(UserClaims)
	h.client.Set(ctx, uc.Ssid, "expired", h.rtExpiration)
	return nil
}

func (h *RedisJWTHandler) CheckSession(ctx *gin.Context, ssid string) error {
	cnt, err := h.client.Exists(ctx, ssid).Result()
	if err != nil {
		return err
	}
	if cnt > 0 {
		return errors.New("token已失效")
	}
	return nil
}

type UserClaims struct {
	jwt.RegisteredClaims
	Id        uint64
	Ssid      string
	UserAgent string
}
